<template>
  <basic-dialog
    title="设置显示字段"
    width="450px"
    :visible="dialogVisible"
    :handleClose="handleCloseDialog"
    :show-footer="false"
  >
    <el-row>
      <el-col :span="14">
        <el-input v-model="formData.label"></el-input>
      </el-col>
      <el-col :span="10">
        <el-row type="flex" justify="center" align="middle">
          <el-button @click="handleSearch">查询</el-button>
          <el-divider direction="vertical"></el-divider>
          <el-button
            type="primary"
            @click="handleCompleteConfig"
            :loading="btnLoading.submit"
          >完成配置</el-button>
        </el-row>
      </el-col>
    </el-row>
    <el-row class="fixed_col_wrap" type="flex" align="middle">
      <p>锁定前</p>
      <el-input-number
        v-model="formData.fixedNum"
        :controls="false"
        :min="0"
        :max="10"
      ></el-input-number>
      <p>列</p>
    </el-row>
    <BasicTable
      ref="settingTable"
      class="columns_setting_table"
      :rowKey="rowKey"
      :border="false"
      :showSelectCol="false"
      :showPagination="false"
      :dataSource="tableInfo.list"
      :columns="tableInfo.columns"
      :loading="tableInfo.loading"
      :tableHeight="480"
    />
  </basic-dialog>
</template>
<script>
import Sortable from 'sortablejs';
import { requestToData, requestToStatus } from '@/api/commonHttp';
import BasicDialog from '@/components/BasicDialog';
import BasicTable from '@/components/BasicTable';
export default {
  components: {
    BasicDialog,
    BasicTable
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    rowKey: {
      type: String,
      default: 'id'
    },
    hasBorder: {
      type: Boolean,
      default: false
    },
    tableColumns: {
      type: Array
    },
    queryApi: {
      type: Object,
      default () { return {}; }
    },
    submitUrl: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      dialogVisible: false, // 弹框显隐开关
      formData: {
        label: '',
        fixedNum: null
      },
      tableInfo: {
        list: [],
        columns: [],
        loading: false
      },
      btnLoading: {
        submit: false
      }
    }
  },
  watch: {
    visible (val) {
      this.dialogVisible = val;
      if (val) {
        this.setTableColumns();
        this.getTableData();
        this.$nextTick(() => {
          this.dropTableRow();
        });
      }
    }
  },
  methods: {
    // 查询
    handleSearch () {
      if (!this.formData.label) { return this.$message.warning('请输入查询条件'); }
      const index = this.tableInfo.list.findIndex(item => item.columnName === this.formData.label);
      if (index === -1) { return this.$message.warning('未查询到相关字段，请精确查询条件') }
      this.anchorPointPositing(index);
    },
    // 关闭弹框
    handleCloseDialog () {
      this.$emit('update:visible', false);
    },
    // 置顶
    handleToTop (index) {
      const currentRow = this.tableInfo.list.splice(index, 1)[0];
      this.tableInfo.list.unshift(currentRow);
    },
    // 置底
    handleToBottom (index) {
      const currentRow = this.tableInfo.list.splice(index, 1)[0];
      this.tableInfo.list.push(currentRow);
    },
    // 完成配置
    handleCompleteConfig () {
      const isNullShowColumn = this.tableInfo.list.filter(item => item.isShow).length === 0;
      if (isNullShowColumn) { return this.$message.warning('至少保留一个展示字段'); }
      this.submitConfigData();
    },
    // 拖拽行
    dropTableRow () {
      const tbodySelector = document.querySelector('.columns_setting_table .el-table__body-wrapper tbody');
      Sortable.create(tbodySelector, {
        animation: 500,
        easing: 'cubic-bezier(1, 0, 0, 1)',
        onEnd: ({ newIndex, oldIndex }) => { // 如果不使用箭头函数，则需要在外面存储vue的this，否则会指向Sortable
          const currentRow = this.tableInfo.list.splice(oldIndex, 1)[0];
          this.tableInfo.list.splice(newIndex, 0, currentRow);
        }
      });
    },
    // jsx-render 渲染switch开关
    jsxRenderSwitch (h, { row }) {
      return <el-switch
        v-model={row.isShow}
        disabled={!row.canOperation}
        active-value={1}
        inactive-value={0}
        width={28}
      />
    },
    // jsx-render 渲染列宽输入
    jsxRenderWidthInput (h, { row }) {
      return <el-input-number
        v-model={row.width}
        controls-position="right"
        size="mini"
        controls={false}
        min={80}
      />
    },
    // jsx-render 渲染操作栏
    jsxRenderBtnsBar (h, { index }) {
      const toTopBtn = <el-button
        type="text"
        onClick={() => { this.handleToTop(index) }}
      >置顶</el-button>
      const toBottomBtn = <el-button
        type="text"
        onClick={() => { this.handleToBottom(index) }}
      >置底</el-button>
      if (index === 0) { return toBottomBtn; }
      if (index === this.tableInfo.list.length - 1) { return toTopBtn; }
      return <div class="table-action">{toTopBtn} {toBottomBtn}</div>
    },
    // 表格行定位
    anchorPointPositing (index) {
      const elTable = this.$refs.settingTable.$refs.elTable.$el;
      const scrollParent = elTable.querySelector('.el-table__body-wrapper')
      const targetTop = elTable.querySelectorAll('.el-table__body tr')[index].getBoundingClientRect().top // 该行的位置
      const containerTop = elTable.querySelector('.el-table__body').getBoundingClientRect().top // body的位置
      scrollParent.scrollTop = targetTop - containerTop;
    },
    // 设置表列
    setTableColumns () {
      if (this.tableColumns) {
        this.tableInfo.columns = this.tableColumns;
      } else {
        this.tableInfo.columns = this.getDefaultColumns();
      }
    },
    // 提交数据配置
    async submitConfigData () {
      const data = this.tableInfo.list.map((item, index) => ({
        ...item,
        sort: index,
        fixedColumnNum: this.formData.fixedNum
      }));
      const retStatus = await requestToStatus({
        url: this.submitUrl,
        type: 'post',
        data
      },
      () => { this.btnLoading.submit = true; },
      () => { this.btnLoading.submit = false; });
      if (retStatus) {
        this.$message.success('表列配置成功');
        this.$emit('getTableColumns', data);
        this.$emit('update:visible', false);
      }
    },
    // 获取表格数据
    async getTableData () {
      const { url, type, data, isFormData } = this.queryApi;
      const retData = await requestToData({
        url,
        type: type || 'get',
        data,
        isFormData
      },
      () => { this.tableInfo.loading = true; },
      () => { this.tableInfo.loading = false; });
      if (retData) {
        // width 如果没值 默认值给出120
        this.tableInfo.list = retData.map(item => ({ ...item, width: item.width || 120 }));
        this.formData.fixedNum = this.tableInfo.list[0].fixedColumnNum;
      }
    },
    // 获取默认表列
    getDefaultColumns () {
      return [
        {
          title: '显示',
          width: 70,
          notShowTip: true,
          render: (h, info) => {
            return this.jsxRenderSwitch(h, info);
          }
        },
        {
          title: '名称',
          key: 'columnName',
          width: 84,
          align: 'left',
        },
        {
          title: '列宽',
          width: 90,
          notShowTip: true,
          render: (h, info) => {
            return this.jsxRenderWidthInput(h, info);
          }
        },
        {
          title: '操作',
          width: 80,
          notShowTip: true,
          render: (h, info) => {
            return this.jsxRenderBtnsBar(h, info);
          }
        }
      ]
    },
  }
}
</script>
<style lang="less" scoped>
/deep/ .el-switch {
  height: 16px;
  line-height: 16px;
  .el-switch__core {
    height: 14px;
    border-radius: 14px;
    &:after {
      width: 12px;
      height: 12px;
      top: 0;
    }
  }
  &.is-checked .el-switch__core::after {
    margin-left: -12px;
  }
}
/deep/ .el-input-number {
  &.el-input-number--mini{
    width: 90px;
  }
  .el-input__inner {
    width: 54px;
    height: 24px;
    padding: 0 5px;
    border-radius: 14px;
    text-align: center;
  }
}
/deep/ .columns_setting_table {
  .el-table__row { // 鼠标悬浮标志
    cursor: move;
  }
  .el-table {
    th:nth-child(2) { // 表格第二列表头居左
      text-align: left !important;
    }
    tr td:nth-child(3) .cell { // 第三列列宽不展示超出省略号
      text-overflow: clip !important;
    }
  }
}
.fixed_col_wrap {
  margin-top: 10px;
  padding: 5px 0px;
  border-top: 1px dashed #ccc;
  border-bottom: 1px dashed #ccc;
  .el-input-number {
    margin: 0 10px;
  }
  /deep/ .el-input-number--small {
    width: 54px !important;
  }
}
</style>
